package com.satan.config.security;

import cn.hutool.core.util.StrUtil;
import com.satan.constant.JwtConstant;
import com.satan.entity.SysUser;
import com.satan.entity.response.CheckResult;
import com.satan.service.SysUserService;
import com.satan.util.JwtUtil;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtException;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import java.io.IOException;
import java.util.List;

@Slf4j
@Component
@RequiredArgsConstructor
public class JwtAuthenticationFilter extends OncePerRequestFilter {
    @Value("${url_white_list}")
    private final List<String> urlWhiteList;
    private final SysUserService sysUserService;
    private final MyUserDetailsService myUserDetailsService;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException, IOException {
        String token = request.getHeader(HttpHeaders.AUTHORIZATION);
        log.info("token={}", token);
        String uri = request.getRequestURI();
        log.info("请求的uri:{}", uri);
        String method = request.getMethod();
        log.info("请求方式:"+method);
        //如果token非空或者在白名单就放行
        log.info("路径白名单:{}", urlWhiteList);
        if (!urlWhiteList.contains(uri)&& StrUtil.isNotEmpty(token)) {
            log.info("开始校验token!");
            //验证token
            CheckResult checkResult = JwtUtil.validateJWT(token);
            if (!checkResult.isSuccess()) {
                switch (checkResult.getErrCode()) {
                    case JwtConstant.JWT_ERRCODE_NULL:
                        throw new JwtException("token不存在");
                    case JwtConstant.JWT_ERRCODE_FAIL:
                        throw new JwtException("Token验证不通过");
                    case JwtConstant.JWT_ERRCODE_EXPIRE:
                        throw new JwtException("Token过期");
                }
            }
            Claims claims = JwtUtil.parseJwt(token);
            String username = claims.getSubject();
            SysUser sysUser = sysUserService.getUserByName(username);
            UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(sysUser.getUsername(), null, myUserDetailsService.getUserAuthority(sysUser.getId()));
            SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
        }



        filterChain.doFilter(request, response);
    }
}
